package com.v1.web.action;

import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import com.v1.cache.CategoryCache;
import com.v1.model.Category;
import com.v1.util.Constant;
import com.v1.util.Toolkit;

/**
 * @author:luyang
 */
public class BaseAction extends DispatchAction {
	protected static final String NEXTURL = "nexturl";

	protected final Log log = LogFactory.getLog(getClass());

	protected static final ActionForward INDEX = new ActionForward("", "/index.html", true, "");;
	protected static final ActionForward ERROR = new ActionForward("", "/error.html", true, "");
	protected static final ActionForward LOGIN = new ActionForward("", "/login.html", true, "");

	protected ActionForward getErrorForward() {
		return ERROR;
	}

	protected ActionForward goLogin(HttpServletRequest request) {
		String nexturl = request.getRequestURL().toString();
		setAttributeToSession(request, NEXTURL, nexturl);
		return LOGIN;
	}

	protected String getMethodName(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response, String parameter) throws Exception {
		if (StringUtils.isEmpty(parameter)) {
			return null;
		}
		if ("path".equals(parameter)) {
			return mapping.getPath().substring(1);
		}

		Enumeration<?> e = request.getParameterNames();
		while (e.hasMoreElements()) {
			String currentName = (String) e.nextElement();

			if (currentName.startsWith(parameter + ".")) {
				log.debug("calling method: " + currentName);
				String[] split = currentName.split("\\.");
				return split[1];
			}
		}
		return null;
	}

	protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response, String name) throws Exception {
		try {
			ActionForward before = before(request, response);
			if (before != null) {
				return before;
			}
			ActionForward dispatchMethod = super.dispatchMethod(mapping, form, request, response, name);
			ActionForward after = after(request, response);
			if (after != null) {
				return after;
			}
			return dispatchMethod;
		} catch (Exception e) {
			log.error(e, e);
			return getErrorForward();
		}
	}

	protected ActionForward after(HttpServletRequest request, HttpServletResponse response) {
		return null;
	}

	protected ActionForward before(HttpServletRequest request, HttpServletResponse response) {
		Constant constant = (Constant) getBean("Constant");
		setAttribute(request, "appkey", constant.APPKEY);
		return null;
	}

	/**
	 * Convenience method to get Spring-initialized beans
	 * 
	 * @param name
	 *            name
	 * @return Object bean from ApplicationContext
	 */
	public final Object getBean(String name) {
		Toolkit toolkit = Toolkit.getInstance();
		return toolkit.getBean(name);
	}

	protected void setAttribute(HttpServletRequest request, String name, Object value) {
		request.setAttribute(name, value);
	}

	protected Object getAttribute(HttpServletRequest request, String parameter) {
		return request.getAttribute(parameter);
	}

	protected void removeAttributeFromSession(HttpServletRequest request, String name) {
		HttpSession session = request.getSession();
		session.removeAttribute(name);
	}

	public void setAttributeToSession(HttpServletRequest request, String name, Object value) {
		HttpSession session = request.getSession();
		session.setAttribute(name, value);
	}

	protected Object getAttributeFromSession(HttpServletRequest request, String parameter) {
		return getAttributeFromSession(request, parameter, true);
	}

	protected Object getAttributeFromSession(HttpServletRequest request, String parameter, boolean remain) {
		HttpSession session = request.getSession();
		Object attributeFromSession = session.getAttribute(parameter);
		if (!remain) {
			session.removeAttribute(parameter);
		}
		return attributeFromSession;
	}

	protected Integer getInteger(HttpServletRequest request, String parameter, int defaultValue,
			boolean remain) {
		String value = request.getParameter(parameter);
		int i = NumberUtils.toInt(value, defaultValue);
		if (remain) {
			setAttribute(request, parameter, i);
		}
		return i;
	}

	protected Integer getInteger(HttpServletRequest request, String parameter, int defaultValue) {
		return getInteger(request, parameter, defaultValue, false);
	}

	protected Integer getInteger(HttpServletRequest request, String parameter) {
		return getInteger(request, parameter, false);
	}

	protected Integer getInteger(HttpServletRequest request, String parameter, boolean remain) {
		String value = request.getParameter(parameter);
		if (StringUtils.isEmpty(value)) {
			return null;
		}

		int i = NumberUtils.toInt(value);
		if (remain) {
			setAttribute(request, parameter, i);
		}
		return i;
	}

	protected String getString(HttpServletRequest request, String parameter) {
		return getString(request, parameter, false);
	}

	protected String getString(HttpServletRequest request, String parameter, boolean remain) {
		return getString(request, parameter, remain, "");
	}

	protected String getString(HttpServletRequest request, String parameter, boolean remain,
			String defaultValue) {
		String value = request.getParameter(parameter);
		value = StringUtils.defaultIfEmpty(value, defaultValue);
		if (remain) {
			setAttribute(request, parameter, value);
		}
		return value;
	}

	protected String[] getStrings(HttpServletRequest request, String parameter) {
		return getStrings(request, parameter, false);
	}

	protected String[] getStrings(HttpServletRequest request, String parameter, boolean remain) {
		return getStrings(request, parameter, remain, "");
	}

	protected String[] getStrings(HttpServletRequest request, String parameter, boolean remain,
			String defaultValue) {
		String[] values = request.getParameterValues(parameter);
		if (ArrayUtils.isEmpty(values)) {
			values = new String[0];
		}
		if (remain) {
			setAttribute(request, parameter, values);
		}
		return values;
	}

	protected ActionForward statusForward(ActionMapping mapping, String forwardName, Object... arguments) {
		ActionForward forward = mapping.findForward(forwardName);
		String path = forward.getPath();
		path = MessageFormat.format(path, arguments);
		ActionForward copy = new ActionForward(forward);
		copy.setPath(path);
		return copy;
	}

	protected void setMenu(HttpServletRequest request) {
		CategoryCache categoryCache = (CategoryCache) getBean("CategoryCache");
		List<Category> list = categoryCache.getSubCategorys(0);
		request.setAttribute("menu", list);
	}

	protected void setParents(HttpServletRequest request) {
		CategoryCache categoryCache = (CategoryCache) getBean("CategoryCache");
		Integer categoryid = getInteger(request, "categoryid", 0);
		List<Category> parents = categoryCache.getParents(categoryid);
		request.setAttribute("parents", parents);
	}
}
